home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / Filezilla Server / FileZilla_Server-0_9_41.exe / source / hash_thread.cpp < prev    next >
C/C++ Source or Header  |  2011-11-06  |  5KB  |  274 lines

  1. #include "StdAfx.h"
  2. #include "hash_thread.h"
  3. #include "misc\md5.h"
  4. #include "ServerThread.h"
  5.  
  6. #define SHA512_STANDALONE
  7. typedef unsigned int uint32;
  8. #include "hash_algorithms/int64.h"
  9. #include "hash_algorithms/sshsh512.c"
  10. #include "hash_algorithms/sshsha.c"
  11.  
  12. CHashThread::CHashThread()
  13. {
  14.     m_filename = 0;
  15.     m_quit = false;
  16.     m_id = 0;
  17.     m_active_id = 0;
  18.     m_result = OK;
  19.     m_hash = 0;
  20.     m_server_thread = 0;
  21.     m_algorithm = SHA512;
  22.  
  23.     m_hThread = CreateThread(0, 0, &CHashThread::ThreadFunc, this, 0, 0);
  24.  
  25. }
  26.  
  27. CHashThread::~CHashThread()
  28. {
  29.     m_sync.Lock();
  30.     m_quit = true;
  31.     m_server_thread = 0;
  32.     delete [] m_filename;
  33.     delete [] m_hash;
  34.     m_sync.Unlock();
  35.  
  36.     WaitForSingleObject(m_hThread, INFINITE);
  37.  
  38.     CloseHandle(m_hThread);
  39. }
  40.  
  41. DWORD CHashThread::ThreadFunc(LPVOID pThis)
  42. {
  43.     ((CHashThread*)pThis)->Loop();
  44.  
  45.     return 0;
  46. }
  47.  
  48. namespace {
  49. char* toHex(unsigned char* buffer, unsigned int len)
  50. {
  51.     char* hex = new char[len * 2 + 1];
  52.     hex[len * 2] = 0;
  53.  
  54.     for (unsigned int i = 0; i < len; i++)
  55.     {
  56.         unsigned char l = buffer[i] >> 4;
  57.         unsigned char r = buffer[i] & 0x0F;
  58.  
  59.         if (l > 9)
  60.             hex[i * 2] = 'a' + l - 10;
  61.         else
  62.             hex[i * 2] = '0' + l;
  63.  
  64.         if (r > 9)
  65.             hex[i * 2 + 1] = 'a' + r - 10;
  66.         else
  67.             hex[i * 2 + 1] = '0' + r;
  68.     }
  69.  
  70.     return hex;
  71. }
  72. }
  73.  
  74. void CHashThread::DoHash()
  75. {
  76.     if (!m_filename)
  77.         return;
  78.  
  79.     LPCTSTR file = m_filename;
  80.     m_filename = 0;
  81.  
  82.     m_sync.Unlock();
  83.  
  84.     int shareMode = FILE_SHARE_READ;
  85.     HANDLE hFile = CreateFile(file, GENERIC_READ, shareMode, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
  86.     delete [] file;
  87.     
  88.     if (hFile == INVALID_HANDLE_VALUE)
  89.     {
  90.         m_sync.Lock();
  91.         m_result = FAILURE_OPEN;
  92.         if (m_server_thread)
  93.             m_server_thread->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_HASHRESULT, m_active_id);
  94.         return;
  95.     }
  96.  
  97.     const enum _algorithm alg = m_algorithm;
  98.  
  99.     void* data;
  100.     switch (alg)
  101.     {
  102.     case MD5:
  103.         data = new ::MD5;
  104.         break;
  105.     case SHA512:
  106.         data = new SHA512_State;
  107.         SHA512_Init((SHA512_State*)data);
  108.         break;
  109.     case SHA1:
  110.         data = new SHA_State;
  111.         SHA_Init((SHA_State*)data);
  112.         break;
  113.     }
  114.  
  115.     unsigned char buffer[262144];
  116.     DWORD read = 0;
  117.     BOOL res = 0;
  118.     while ((res = ReadFile(hFile, buffer, 262144, &read, 0) != 0) && read > 0)
  119.     {
  120.         switch (alg)
  121.         {
  122.         case MD5:
  123.             ((::MD5*)data)->update(buffer, read);
  124.             break;
  125.         case SHA512:
  126.             SHA512_Bytes((SHA512_State*)data, buffer, read);
  127.             break;
  128.         case SHA1:
  129.             SHA_Bytes((SHA_State*)data, buffer, read);
  130.             break;
  131.         }
  132.  
  133.         m_sync.Lock();
  134.         if (!m_server_thread)
  135.         {
  136.             CloseHandle(hFile);
  137.             return;
  138.         }
  139.         m_sync.Unlock();
  140.     }
  141.  
  142.     CloseHandle(hFile);
  143.  
  144.  
  145.     if (!res)
  146.     {
  147.         m_sync.Lock();
  148.         m_result = FAILURE_READ;
  149.         if (m_server_thread)
  150.             m_server_thread->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_HASHRESULT, m_active_id);
  151.         return;
  152.     }
  153.  
  154.     m_sync.Lock();
  155.  
  156.     switch (alg)
  157.     {
  158.     case MD5:
  159.         ((::MD5*)data)->finalize();
  160.         m_hash = ((::MD5*)data)->hex_digest();
  161.         break;
  162.     case SHA512:
  163.         {
  164.             unsigned char digest[64];
  165.             SHA512_Final((SHA512_State*)data, digest);
  166.             m_hash = toHex(digest, 64);
  167.         }
  168.         break;
  169.     case SHA1:
  170.         {
  171.             unsigned char digest[20];
  172.             SHA_Final((SHA_State*)data, digest);
  173.             m_hash = toHex(digest, 20);
  174.         }
  175.         break;
  176.     }
  177.     m_result = m_hash ? OK : FAILURE_READ;
  178.     if (m_server_thread)
  179.         m_server_thread->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_HASHRESULT, m_active_id);
  180. }
  181.  
  182. void CHashThread::Loop()
  183. {
  184.     m_sync.Lock();
  185.     while (!m_quit)
  186.     {
  187.         DoHash();
  188.         m_sync.Unlock();
  189.         Sleep(100);
  190.         m_sync.Lock();
  191.     }
  192. }
  193.  
  194. enum CHashThread::_result CHashThread::Hash(LPCTSTR file, enum _algorithm algorithm, int& id, CServerThread* server_thread)
  195. {
  196.     m_sync.Lock();
  197.     if (m_active_id)
  198.     {
  199.         m_sync.Unlock();
  200.         return BUSY;
  201.     }
  202.  
  203.     ++m_id;
  204.     if (m_id > 1000000)
  205.         m_id = 1;
  206.     id = m_id;
  207.     m_active_id = id;
  208.  
  209.     delete [] m_hash;
  210.     m_hash = 0;
  211.  
  212.     delete [] m_filename;
  213.     m_filename = new TCHAR[_tcslen(file) + 1];
  214.     _tcscpy(m_filename, file);
  215.  
  216.     m_server_thread = server_thread;
  217.     m_algorithm = algorithm;
  218.  
  219.     m_result = PENDING;
  220.  
  221.     m_sync.Unlock();
  222.  
  223.     return PENDING;
  224. }
  225.  
  226. enum CHashThread::_result CHashThread::GetResult(int id, CHashThread::_algorithm& alg, CStdString& hash, CStdString& file)
  227. {
  228.     if (id <= 0)
  229.         return FAILURE_MASK;
  230.     
  231.     m_sync.Lock();
  232.     
  233.     if (id != m_active_id)
  234.     {
  235.         m_sync.Unlock();
  236.         return BUSY;
  237.     }
  238.  
  239.     if (m_result == PENDING) 
  240.     {
  241.         m_sync.Unlock();
  242.         return PENDING;
  243.     }
  244.  
  245.     alg = m_algorithm;
  246.     file = m_filename;
  247.  
  248.     delete [] m_filename;
  249.     m_filename = 0;
  250.  
  251.     m_active_id = 0;
  252.  
  253.     if (m_result == OK)
  254.     {
  255.         hash = m_hash;
  256.         delete [] m_hash;
  257.         m_hash = 0;
  258.         m_sync.Unlock();
  259.         return OK;
  260.     }
  261.  
  262.     m_sync.Unlock();
  263.  
  264.     return m_result;
  265. }
  266.  
  267. void CHashThread::Stop(CServerThread* server_thread)
  268. {
  269.     m_sync.Lock();
  270.     if (m_server_thread == server_thread)
  271.         m_server_thread = 0;
  272.     m_sync.Unlock();
  273. }
  274.